package com.ponhu.ea2.goodsCenter.provider.facade.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ponhu.ea2.common.basic.model.PagedResult;
import com.ponhu.ea2.common.basic.model.ResponseBean;
import com.ponhu.ea2.constants.CommonConstant;
import com.ponhu.ea2.constants.DictConstant;
import com.ponhu.ea2.dto.*;
import com.ponhu.ea2.entity.CloudTradeGoods;
import com.ponhu.ea2.entity.Material;
import com.ponhu.ea2.enums.GoodsStatusEnum;
import com.ponhu.ea2.enums.SyncAppletTypeEnum;
import com.ponhu.ea2.goodsCenter.provider.biz.CloudTradeCoreService;
import com.ponhu.ea2.goodsCenter.provider.biz.OperationRecordLogsCoreService;
import com.ponhu.ea2.goodsCenter.provider.service.*;
import com.ponhu.ea2.goodsCenter.provider.utils.DataConverterUtils;
import com.ponhu.ea2.query.CloudTradeGoodsQuery;
import com.ponhu.ea2.service.facade.CloudTradeGoodsManageService;
import com.ponhu.ea2.stockcenter.service.bms.StockForGoodsCenterService;
import com.ponhu.ea2.stockcenter.vo.ReturnResponseBean;
import com.ponhu.ea2.support.exception.BusinessRuntimeException;
import com.ponhu.ea2.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

import static com.ponhu.ea2.constants.CommonConstant.BUSINESS_TYPE_CLOUD_TRADE;
import static com.ponhu.ea2.constants.CommonConstant.CLOUD_TRADE_INVENTORY_CHANNEL;
import static com.ponhu.ea2.enums.ResponseCodeEnum.*;

@Slf4j
@DubboService(version = "1.0.0", interfaceClass = CloudTradeGoodsManageService.class, timeout = 6000)
public class CloudTradeGoodsManageServiceImpl implements CloudTradeGoodsManageService {


    @Autowired
    private CloudTradeGoodsService cloudTradeGoodsService;

    @Autowired
    private PhSysDictItemService dictItemService;
    @Autowired
    private MaterialService materialService;
    @Autowired
    private PhInventoryForCreateByPurchaseService phInventoryForCreateByPurchaseService;
    @Autowired
    private GoodsInfoManagerService goodsInfoManagerService;
    @Autowired
    private CloudTradeCoreService cloudTradeCoreService;
    @DubboReference(version = "1.0.0", check = false)
    private StockForGoodsCenterService stockForGoodsCenterService;
    @Autowired
    private OperationRecordLogsCoreService operationRecordLogsCoreService;

    @Resource
    PhinventoryToAmqpService phinventoryToAmqpService;


    @Override
    public PagedResult<CloudTradeGoodsVO> getCloudTradeGoodsList(CloudTradeGoodsQuery cloudTradeGoodsQuery) {
        IPage<CloudTradeGoods> page = cloudTradeGoodsService.getCloudTradeGoodsList(cloudTradeGoodsQuery);
        List<CloudTradeGoods> records = page.getRecords();

        //成色数据
        Map<String, String> quantityMap = dictItemService.getDictItemList(DictConstant.CONDITION_TYPE, records,
                i -> Objects.toString(i.getQuality(), null));

        //货源数据
        Map<String, String> inventorySourceMap = dictItemService.getDictItemList(DictConstant.INVENTORY_SOURCE, records,
                i -> Objects.toString(i.getAccountId(), null));

        //入库方式数据
        Map<String, String> inWayMap = dictItemService.getDictItemList(DictConstant.GOTOWARE_TYPE, records,
                i -> Objects.toString(i.getInWay(), null));

        //字典数据转换
        List<CloudTradeGoodsVO> collect = records.stream().map(i -> {
            CloudTradeGoodsVO cloudTradeGoodsVO = new CloudTradeGoodsVO();
            BeanUtils.copyProperties(i, cloudTradeGoodsVO);
            if (i.getQuality() != null && CollectionUtils.isNotEmpty(quantityMap)) {
                cloudTradeGoodsVO.setQualityName(quantityMap.get(i.getQuality().toString()));
            }
            if (i.getAccountId() != null && CollectionUtils.isNotEmpty(inventorySourceMap)) {
                cloudTradeGoodsVO.setInventorySource(inventorySourceMap.get(i.getAccountId().toString()));
            }
            if (i.getInWay() != null && CollectionUtils.isNotEmpty(inWayMap)) {
                cloudTradeGoodsVO.setInWayName(inWayMap.get(i.getInWay().toString()));
            }
            cloudTradeGoodsVO.setInventoryName(i.getGoodsName());

            return cloudTradeGoodsVO;
        }).collect(Collectors.toList());

        return DataConverterUtils.convertToPagedResult(page, collect);
    }

    @Deprecated
    @Override
    public CloudTradeGoodsDetailVO getCloudTradeGoodsDetailById(Long cloudTradeGoodsId) {
        if (cloudTradeGoodsId == null) {
            return null;
        }

        return cloudTradeGoodsService.getCloudTradeGoodsDetailById(cloudTradeGoodsId);
    }

    @Override
    public CloudTradeGoodsDetailV2VO getCloudTradeGoodsDetailByIdV2(Long cloudTradeGoodsId) {
        if (cloudTradeGoodsId == null) {
            return null;
        }

        return cloudTradeGoodsService.getCloudTradeGoodsDetailByIdV2(cloudTradeGoodsId);
    }

    @Deprecated
    @Override
    public CloudTradeGoodsDetailVO getCloudTradeGoodsDetailByChannelGoodsCode(String channelGoodsCode) {
        if (channelGoodsCode == null) {
            return null;
        }

        return cloudTradeGoodsService.getCloudTradeGoodsDetailByChannelGoodsCode(channelGoodsCode);
    }

    @Override
    public CloudTradeGoodsDetailV2VO getCloudTradeGoodsDetailByChannelGoodsCodeV2(String channelGoodsCode) {
        return cloudTradeGoodsService.getCloudTradeGoodsDetailByChannelGoodsCodeV2(channelGoodsCode);
    }

    /**
     * 审核云商商品信息
     * @param checkDto
     * @return
     */
    @Override
    public boolean checkCloudTradeGoods(CloudTradeGoodsCheckDto checkDto) {
        //审核云商商品数据并分发数据至商品中心
        PhInventoryForCloudTradeDto inventoryForCloudTradeDto = cloudTradeGoodsService.checkCloudTradeGoodsAndDispatchDataToGoodsCenter(checkDto);
        //分发商品数据至胖总管、WMS
        if(ObjectUtils.isNotEmpty(inventoryForCloudTradeDto)){
            cloudTradeCoreService.dispatchDataToPonhuAndWMS(inventoryForCloudTradeDto);
        }
        return true;
    }



    private ResponseBean<PhInventoryBaseVo> createInventoryAndGoods(CloudTradeGoods goods) {
        Material material = materialService.getOneMaterialByCode(goods.getMaterialCode());
        if (material == null) {
            throw new BusinessRuntimeException(MATERIAL_DATA_NOT_EXISTS_800401);
        }

        //组装数据
        PhInventoryForPurchaseDto phInventoryForPurchaseDto = new PhInventoryForPurchaseDto();
        phInventoryForPurchaseDto.setImages(goods.getDetailImage())
                .setWarehousingMethodId(DataConverterUtils.convertToString(goods.getInWay()))
                .setIsTwoLuxury(CommonConstant.YES_OR_NO.YES)
                .setInventoryChannel(CLOUD_TRADE_INVENTORY_CHANNEL)
                .setCategoryId(DataConverterUtils.convertToString(material.getCategoryId()))
                .setQuality(DataConverterUtils.convertToString(goods.getQuality()))
                ;

        return phInventoryForCreateByPurchaseService.createOrUpdateGoods(phInventoryForPurchaseDto);
    }

    /**
     * 根据云商渠道商品编码下架商品
     * @param channelGoodsCode
     * @return
     */
    @Override
    public boolean downShelf(String channelGoodsCode) {
        CloudTradeGoods cloudTradeGoods = cloudTradeGoodsService.getCloudTradeGoodsByChannelGoodsCode(channelGoodsCode);
        if(cloudTradeGoods == null){
            throw new BusinessRuntimeException(CLOUD_TRADE_GOODS_NOT_EXISTS_800100);
        }

        cloudTradeGoodsService.downShelf(channelGoodsCode);

        CompletableFuture.runAsync(() -> {
            ReturnResponseBean<Boolean> result = stockForGoodsCenterService.deleteVirtualSalesStockData(Collections.singletonList(channelGoodsCode));
            if (result.getCode() != CommonConstant.SUCCESS) {
                log.error("下架云商商品扣减虚拟库存失败 ===> {}", result);
            }else {
                log.info("下架云商商品扣减虚拟库存成功");
            }
        });
        //下架状态同步其它系统
        return goodsInfoManagerService.editGoodsStatus(channelGoodsCode, GoodsStatusEnum.PUT_SHELF.getCode(),
                "云商系统请求商品中心下架商品", "system", 0L);
    }

    @Override
    public boolean upShelf(String channelGoodsCode) {
        CloudTradeGoods cloudTradeGoods = cloudTradeGoodsService.getCloudTradeGoodsByChannelGoodsCode(channelGoodsCode);
        if(cloudTradeGoods == null){
            throw new BusinessRuntimeException(CLOUD_TRADE_GOODS_NOT_EXISTS_800100);
        }

        cloudTradeGoodsService.upShelf(channelGoodsCode);

        CompletableFuture.runAsync(() -> {
            ReturnResponseBean<Boolean> result = stockForGoodsCenterService.addOneVirtualSalesStockData(Collections.singletonList(channelGoodsCode));
            if (result.getCode() != CommonConstant.SUCCESS) {
                log.error("上架云商商品增加虚拟库存失败 ===> {}", result);
            }else {
                log.info("上架云商商品增加虚拟库存成功");
            }
        });

        //下架状态同步其它系统
        return goodsInfoManagerService.editGoodsStatus(channelGoodsCode, GoodsStatusEnum.ON_SHELF.getCode(),
                "云商系统请求商品中心上架商品", "system", 0L);
    }

    /**
     * 编辑云商商品
     * @param cloudTradeGoodsEditDto
     * @return
     */
    @Override
    public boolean editCloudTradeGoods(CloudTradeGoodsEditDto cloudTradeGoodsEditDto) {
        CloudTradeGoods cloudTradeGoods = cloudTradeGoodsService.getById(cloudTradeGoodsEditDto.getId());
        if (cloudTradeGoods == null) {
            throw new BusinessRuntimeException(CLOUD_TRADE_GOODS_NOT_EXISTS_800100);
        }
        //只有待审核商品可以编辑
        if (CommonConstant.CLOUD_TRADE_GOODS_STATUS.NO_CHECK != cloudTradeGoods.getStatus()) {
            throw new BusinessRuntimeException(CLOUD_TRADE_GOODS_EDIT_EXCEPTION_800108);
        }

        CloudTradeGoodsEditDto oldObj = new CloudTradeGoodsEditDto();
        oldObj.setInPrice(cloudTradeGoods.getInPrice());
        oldObj.setSupplyPrice(cloudTradeGoods.getSupplyPrice());
        oldObj.setAdvicePrice(cloudTradeGoods.getAdvicePrice());

        //更新云商商品价格
        cloudTradeGoodsService.update(Wrappers.lambdaUpdate(CloudTradeGoods.class)
                .set(CloudTradeGoods::getInPrice, cloudTradeGoodsEditDto.getInPrice())
                .set(CloudTradeGoods::getSupplyPrice, cloudTradeGoodsEditDto.getSupplyPrice())
                .set(CloudTradeGoods::getAdvicePrice, cloudTradeGoodsEditDto.getAdvicePrice())
                .eq(CloudTradeGoods::getId, cloudTradeGoods.getId())
        );

        //记录更新日志
        LogsForTableColumnsChangeDto<CloudTradeGoodsEditDto> columnsChangeDto = new LogsForTableColumnsChangeDto<>();
        columnsChangeDto.setOldObj(oldObj);
        columnsChangeDto.setNewObj(cloudTradeGoodsEditDto);
        columnsChangeDto.setBusinessTable(BUSINESS_TYPE_CLOUD_TRADE);
        columnsChangeDto.setRecordId(cloudTradeGoodsEditDto.getId());
        columnsChangeDto.setOperator(cloudTradeGoodsEditDto.getOperatorName());
        columnsChangeDto.setOperatorId(cloudTradeGoodsEditDto.getOperatorId());

        operationRecordLogsCoreService.addTableColumnsChangeOperationRecordLogs(columnsChangeDto);
        /*// 同步会员小程序
        CompletableFuture.runAsync(() ->{
            phinventoryToAmqpService.pushDataToAmqp(
                    Arrays.asList(cloudTradeGoods.getChannelGoodsCode()),
                    SyncAppletTypeEnum.PH_INVENTORY_DATA.getCode());
        });*/

        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean updateCloudTradeGoods(CloudTradeGoods cloudTradeGoods,CloudTradeGoodsEditDto cloudTradeGoodsEditDto){
        //更新云商商品价格
        return cloudTradeGoodsService.update(Wrappers.lambdaUpdate(CloudTradeGoods.class)
                .set(CloudTradeGoods::getInPrice, cloudTradeGoodsEditDto.getInPrice())
                .set(CloudTradeGoods::getSupplyPrice, cloudTradeGoodsEditDto.getSupplyPrice())
                .set(CloudTradeGoods::getAdvicePrice, cloudTradeGoodsEditDto.getAdvicePrice())
                .eq(CloudTradeGoods::getId, cloudTradeGoods.getId())
        );
    }

}
